package arg

import (
	"db2s/global"
	"encoding/json"
	"fmt"
	"github.com/gurkankaymak/hocon"
	"os"
	"reflect"
	"strings"
)

func (rc *ConfigParameter) objectXlsDefinitionFunc() (map[string]any, map[string]string, map[string]reflect.Type) {
	var (
		sheetName      map[string]any
		sheetTail      map[string]string
		sheetStructMap map[string]reflect.Type
	)
	sheetName = map[string]any{"terminal": "db2s_terminal",
		"sheetName": global.AnySliceToStringSlice(global.StructNameJsonToSlice(global.MetaTitleSheetName{})),
		"fileName":  "db2s_object_Result"}
	sheetTail = map[string]string{
		"terminal":      global.AnySliceToString(global.StructNameJsonToSlice(global.TObject{})),
		"convertRecord": global.AnySliceToString(global.StructNameJsonToSlice(global.MetaConvertTitle{})),
		"execRecord":    global.AnySliceToString(global.StructNameJsonToSlice(global.MetaExecTitle{})),
		"missTable":     global.AnySliceToString(global.StructNameJsonToSlice(global.XObjectMissTable{}))}
	sheetStructMap = map[string]reflect.Type{
		"terminal":      reflect.TypeOf(global.TObject{}),
		"convertRecord": reflect.TypeOf(global.MetaConvertTitle{}),
		"execRecord":    reflect.TypeOf(global.MetaExecTitle{}),
		"missTable":     reflect.TypeOf(global.XObjectMissTable{}),
	}
	return sheetName, sheetTail, sheetStructMap
}

func getObjectRules() objectLevel {
	return objectLevel{
		Object:            []string{"view", "job", "procedure", "func", "trigger", "packge", "foreign", "seq"},
		AlterRule:         "many",
		BreakPoint:        false,
		SqlLogBin:         false,
		WriteParameterOpt: false,
	}
}

type ObjectS struct {
	Object            []string            `json:"object"`
	Plan              map[string][]string `json:"plan"`
	SalterSqlRule     string              `json:"alterRule"`
	SqlMode           bool                `json:"sqlMode"`
	Breakpoint        bool                `json:"breakpoint"`
	SqlLogBin         bool                `json:"logBin"`
	Scn               string              `json:"scn"`
	TimeOut           []int               `json:"timeOut"`
	Drop              bool                `json:"drop"`
	TimeOutNew        TimeOut
	Case              bool `json:"case"`
	WriteParameterOpt bool `json:"paramOpt"`
	ErrorSqlFile      string
	ErrorSqlFilePoint *os.File
	BreakPointFin     *os.File
}

type objectLevel struct {
	Object            []string            `json:"object"`
	Plan              map[string][]string `json:"plan"`
	Drop              bool                `json:"drop"`
	AlterRule         string              `json:"alterRule"`
	SqlMode           bool                `json:"sqlMode"`
	BreakPoint        bool                `json:"breakpoint"`
	SqlLogBin         bool                `json:"logBin"`
	Case              bool                `json:"case"`
	WriteParameterOpt bool                `json:"paramOpt"`
}

// objectRuleParameter
func objectRuleParameter(hocon *hocon.Config) (Object ObjectS, err error) {
	var (
		objectMap map[string]any
	)
	if objectMap, err = global.StructToMapAny(getObjectRules()); err != nil {
		return
	}
	var s2 []string
	for k, v := range objectMap {
		if r1 := rc.getHoconConfigVal1(hocon, k, reflect.TypeOf(v).String()); r1 != nil {
			s2 = append(s2, rc.anyToJsonString(k, r1))
		} else {
			s2 = append(s2, rc.anyToJsonString(k, v))
		}
	}
	if err = json.Unmarshal([]byte(strings.ReplaceAll(fmt.Sprintf("{%s}", strings.Join(s2, ",")), "\\", "\\\\")), &Object); err != nil {
		return
	}
	return
}

func objectParameterCheck(s *SecondaryLevel) (err error) {
	var (
		objectFixRuleOptionMap map[string]any
	)
	if objectFixRuleOptionMap, err = global.StructSubJsonNameToMap(structFixRuleOptionValue{}); err != nil {
		return
	}
	if !parameterOptions(objectFixRuleOptionMap, s.RulesV.Object.SalterSqlRule) {
		s.RulesV.Object.SalterSqlRule = "many"
	}
	s.RulesV.Object.ErrorSqlFile = "execSqlErr"
	return
}
